import { TrackerConfig, DefaultOptions } from './../types/index';
import { rewriteHistoryFun } from './../utils/pv';

const eventList: string[] = ['click', 'dblclick', 'contextmenu', 'mousedown', 'mouseup', 'mouseenter', 'mouseout', 'mouseover']

class BuryingPoint {

    private _option: DefaultOptions;
    public version: DefaultOptions['sdkVersion'];
    constructor(option: DefaultOptions) {
        this._option = Object.assign(this.initOption(), option);
        this.initTracker();
    }
    private initOption() {
        this.version = TrackerConfig.sdkVersion;
        window.history['pushState'] = rewriteHistoryFun('pushState');
        window.history['replaceState'] = rewriteHistoryFun('replaceState');
        return {
            historyTracker: false,
            hashTracker: false,
            domTracker: false,
            sdkVersion: TrackerConfig.sdkVersion,
            jsError: false
        }
    }

    private initTracker() {
        if (this._option.historyTracker) {
            this.captureEvents(['pushState', 'replaceState', 'popstate'], 'history-pv');
        }

        if (this._option.hashTracker) {
            this.captureEvents(['hashchange'], 'hash-pv');
        }

        if (this._option.jsError) {
            window.addEventListener('error', (event: Event) => {
                this.reportTracker<object>({ event: 'error', targetKey: 'message' });
            })

            window.addEventListener('unhandledrejection', (event: Event) => {
                this.reportTracker<object>({ event: 'unhandledrejection', targetKey: 'reject' });
            })
        }

        if (this._option.domTracker) {
            eventList.forEach(eventName => {
                window.addEventListener(eventName, (event: Event) => {
                    let target = (event.target as HTMLElement)
                    let targetValue = target.getAttribute('target-dom');

                    if (targetValue) {
                        this.reportTracker<object>({ event: eventName, targetKey: targetValue });
                    }
                })
            })
        }
    }

    private captureEvents<T>(eventList: string[], targetKey: string, data?: T) {
        eventList.forEach(eventName => {
            window.addEventListener(eventName, (event: Event) => {
                console.log(eventName, event);
                this.reportTracker<object>({ event: eventName, targetKey, data });
            })
        })
    }

    private reportTracker<T>(data: T) {

        let params = Object.assign(this._option, data, { date: new Date().getTime() })
        let headers = {
            type: 'application/x-www-form-urlencoded'
        };
        let blob = new Blob([JSON.stringify(params)], headers);

        navigator.sendBeacon(this._option.requestUrl, blob)
    }
}

export default BuryingPoint;


